// Test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <memory.h>
#include <windows.h>
#include "..\include\pcv.h"

int CaseOclTest();

int _tmain(
	int						argc,
	_TCHAR*					argv[]
	)
{
	(argc);
	(argv);

	CaseOclTest();

	return 0;
}

int CaseOclTest()
{
	PcvStatus				errcode;

	// initialize OpenPCV library
	errcode = pcvInit();
	
	// allocate memory
	PcvSize					size = {1024, 512};
	PcvRect					roi = {1, 1, 1022, 510};

	unsigned char*			host_src1 = new unsigned char[size.width * size.height];
	unsigned char*			host_src2 = new unsigned char[size.width * size.height];
	unsigned char*			host_dst = new unsigned char[size.width * size.height];
	unsigned char*			device_src1 = (unsigned char*)pcvDeviceMalloc(size.width * size.height);
	unsigned char*			device_src2 = (unsigned char*)pcvDeviceMalloc(size.width * size.height);
	unsigned char*			device_dst = (unsigned char*)pcvDeviceMalloc(size.width * size.height);
	unsigned char*			device_test = (unsigned char*)pcvDeviceMalloc_8u_C1(size);

	memset(host_src1, 255, size.width * size.height);
	memset(host_src2, 2, size.width * size.height);
	memset(host_dst, 0, size.width * size.height);

	// build library function
//	errcode = pcvAdd_8u_C1Rs_Build();
//	errcode = pcvSub_8u_C1Rs_Build();
	errcode = pcvMean_8u_C1Rs_Build();

	// copy image from host memory to device memory
	errcode = pcvCopyHostToDevice(host_src1, device_src1, size.width * size.height);
	errcode = pcvCopyHostToDevice(host_src2, device_src2, size.width * size.height);
	errcode = pcvCopyHostToDevice_8u_C1(host_src2, device_test, size);

	// start test
	LARGE_INTEGER			time_start;
	LARGE_INTEGER			time_end;
	LARGE_INTEGER			time_frequency;
	ZeroMemory(&time_start, sizeof( LARGE_INTEGER));
	ZeroMemory(&time_end, sizeof( LARGE_INTEGER));
	::QueryPerformanceFrequency(&time_frequency);
	::QueryPerformanceCounter(&time_start);
	
	for (int i = 0; i < 100; i++)
	{
//		errcode = pcvAdd_8u_C1Rs(device_src1, device_src2, device_dst, size, roi);
//		errcode = pcvSub_8u_C1Rs(device_src1, device_src2, device_dst, size, roi);
		errcode = pcvMean_8u_C1Rs(device_src1, device_dst, size, roi);
		if (errcode != pcvStsNoErr)
		{
			return 0;
		}
	}

	::QueryPerformanceCounter(&time_end);
	double					time =  1000 * 1.0 * (time_end.QuadPart - time_start.QuadPart) / time_frequency.QuadPart;
	time = time / 100;
	ZeroMemory(&time_start, sizeof(LARGE_INTEGER));
	ZeroMemory(&time_end, sizeof(LARGE_INTEGER));

	errcode = pcvCopyDeviceToHost(device_dst, host_dst, size.width * size.height);


	// check result
	unsigned char dst_point = host_dst[1025];

	delete[] host_src1;
	host_src1 = NULL;
	delete[] host_src2;
	host_src2 = NULL;
	delete[] host_dst;
	host_dst = NULL;
	pcvDeviceFree(device_src1);
	device_src1 = NULL;
	pcvDeviceFree(device_src2);
	device_src2 = NULL;
	pcvDeviceFree(device_dst);
	device_dst = NULL;

	errcode = pcvClean();

	return 0;
}
